<?php

namespace App\Console\Commands\Controller;

use App\Common\Libs\Ali\Oss;
use App\Common\Libs\Ali\RemoteFile;
use App\Common\Libs\ArrayHelper;
use App\Common\Libs\Dispatch\Console;
use App\Common\Libs\HttpClient;
use App\Console\BaseCommand;
use App\Consts\GlobalArticleConst;
use App\Consts\GlobalCacheConst;
use App\Consts\GlobalConsoleConst;
use App\Consts\GlobalConst;
use App\Consts\GlobalUploadConst;
use App\Models\Cache\Cache;
use App\Models\Cache\CacheKey;
use App\Models\SpiderContent;
use App\Models\SysArticle;
use App\Models\SysArticleContent;
use App\Models\SysArticleRepairUrl;

class RepairArticleSrcCommand extends BaseCommand
{
    protected $signature = 'controller:repair-article-src {action} {json}';

    protected $description = 'repair article src commands';

    public function saveImgMap($articleInfo)
    {
        $pattern = "/<img((?!src).)*src[\s]*=[\s]*[\'\"](?<src>[^\'\"]*)[\'\"]/i";
        preg_match_all($pattern, $articleInfo['content'], $out, PREG_PATTERN_ORDER);
        $srcArr = $out['src'];
        $imageRedirectMap = [];
        foreach ($srcArr as $oldSrc) {
            $sign = RemoteFile::getRemoteUrlSign($oldSrc);
            $imageRedirectMap[$sign] = $oldSrc;
        }
        Cache::getInstance([
            'url' => $articleInfo['url']
        ])->hset(CacheKey::ONE_CLICK_COLLECT_REDIRECT_MAP, $imageRedirectMap, GlobalCacheConst::EXPIRED_ONE_HOURS);

        return true;
    }

    public function runs($articleInfo)
    {
        // 获取没有被替换的文章内容
        $spiderRepository = repository()->SpiderRepository;
        $spiderContent = $spiderRepository->getSpiderContent($articleInfo['original_url']);
        if (!$spiderContent) {
            return false;
        }
        $articleInfo['content'] = $spiderContent->original_content;

        // 获取文章信息
        $article = repository()->ArticleRepository->getArticleByArticleId($articleInfo['article_id']);
        if (!$article) {
            return false;
        }

        // 替换封面图
        if (!empty($article->cover_url)) {
            $this->uploadCoverUrl($article->article_id, $article->author_id, $article->cover_url);
        }

        // 替换正文图片
        $this->repairSrc($articleInfo);

        // 将文章信息静态化到第三方
        Oss::getInstance(GlobalUploadConst::OBJECT_ARTICLE_INFO_PATH)->uploadTarget([
            'id' => $article->article_id,
            'title' => $article->title,
            'cover_url' => $article->cover_url,
            'description' => $article->description,
            'content' => $article->contentModel->content,
        ]);

        $url = service()->ConfigService->getConfigByKey('articleContentRefreshUrl') . $article->article_id;
        HttpClient::getInstance()->get($url);

        service()->RecommendSystemService->addTarget([
            'target_id' => $article->article_id,
            'target_type' => GlobalConst::NEW_TARGET_TYPE_QUICK_RECOMMEND_ARTICLE,
            'user_id' => $article->author_id
        ]);

        return true;
    }

    /**
     * @param $data
     */
    private function repairSrc($data)
    {
        $ossUrl = service()->ConfigService->getConfigByKey('ossUrl');

        $oldContent = $data['content'];
        // 获取所有需要上传的正文图片并上传到第三方图片库
        $needDownloadSrcArr = $this->getNeedDownloadSrcArr($data['content']);
        foreach ($needDownloadSrcArr as $oldSrc) {
            $newSrc = Oss::getInstance(
                GlobalUploadConst::OBJECT_ARTICLE_EDITOR_PATH,
                GlobalUploadConst::TYPE_ARTICLE,
                GlobalUploadConst::FROM_FRONTEND,
                $data['article_id']
            )->upload($oldSrc, $data['author_id'], '', [
                'target_id' => $data['article_id'],
                'target_type' => GlobalConst::TARGET_TYPE_ARTICLE,
                'url' => $oldSrc,
                'type' => GlobalUploadConst::REPLACE_RESOURCES_CONTENT,
            ]);
            if ($newSrc) {
                $data['content'] = str_replace($oldSrc, $ossUrl . '/' . GlobalUploadConst::OBJECT_ARTICLE_EDITOR_PATH . $newSrc, $data['content']);
            }

            // 保存替换记录
            $this->saveRepair($data['article_id'], $data['author_id'], $newSrc, $oldSrc);
        }

        // 把旧内容，替换图片后的内容存入[spider_content]
        $this->saveSpiderContent($data['original_url'], $oldContent, $data['content']);

        // 修改[sys_article_content_]内容
        $this->saveArticleContent($data['article_id'], $data['content']);
    }

    /**
     * @param $articleId
     * @param $authorId
     * @param $coverUrl
     * @return bool|SysArticle
     */
    private function uploadCoverUrl($articleId, $authorId, $coverUrl)
    {
        if (!$coverUrl) {
            return false;
        }
        $newCoverUrl = Oss::getInstance(
            GlobalUploadConst::OBJECT_ARTICLE_COVER_PATH,
            GlobalUploadConst::TYPE_ARTICLE,
            GlobalUploadConst::FROM_FRONTEND,
            $articleId
        )->upload($coverUrl, $authorId, '', [
            'target_id' => $articleId,
            'target_type' => GlobalConst::TARGET_TYPE_ARTICLE,
            'url' => $coverUrl,
            'type' => GlobalUploadConst::REPLACE_RESOURCES_COVER
        ]);
        if (!$newCoverUrl) {
            return true;
        }

        $article = repository()->ArticleRepository->getArticleByArticleId($articleId);

        if ($authorId) {
            Console::getInstance(UploadCommand::class)
                ->push([
                    'user_id' => $authorId,
                    'article_id' => $articleId,
                    'original_url' => $coverUrl,
                    'resource_file_name' => $newCoverUrl,
                    'type' => GlobalArticleConst::REPLACE_IMAGE_TYPE_COVER_URL,
                    'status' => GlobalUploadConst::UPLOAD_STATUS_SUCCESS
                ], GlobalConsoleConst::UPLOAD_LOG);
        }


        return repository()->ArticleRepository->updateArticle($article, ['cover_url' => $newCoverUrl]);
    }

    /**
     * 通过文章内容获取需要上传的图片
     * @param $content
     * @return array
     */
    private function getNeedDownloadSrcArr($content)
    {
        $pattern = "/<img((?!src).)*src[\s]*=[\s]*[\'\"](?<src>[^\'\"]*)[\'\"]/i";
        preg_match_all($pattern, $content, $out, PREG_PATTERN_ORDER);
        $allSrcArr = $out['src'];
        $allSrcArr = ArrayHelper::merge($allSrcArr, ['data:image/png']);
        $needDownloadSrcArr = [];
        foreach ($allSrcArr as $src) {
            if (strpos($src, 'data:image') === false && strpos($src, 'tingjun') === false) {
                $needDownloadSrcArr[] = $src;
            }
        }

        return $needDownloadSrcArr;
    }

    /**
     * 保存替换记录
     * @param $articleId
     * @param $authorId
     * @param $resourceFileName
     * @param $originalUrl
     * @return bool
     */
    private function saveRepair($articleId, $authorId, $resourceFileName, $originalUrl)
    {
        $articleRepairUrl = SysArticleRepairUrl::getModel($articleId)->where([
            'article_id' => $articleId,
            'original_url' => $originalUrl,
        ])->first();
        if ($articleRepairUrl) {
            return true;
        }

        SysArticleRepairUrl::getModel($articleId)->update([
            'user_id' => $authorId,
            'article_id' => $articleId,
            'original_url' => $originalUrl,
            'resource_file_name' => $resourceFileName,
            'type' => GlobalArticleConst::REPLACE_IMAGE_TYPE_CONTENT,
        ]);

        if ($authorId) {
            Console::getInstance(UploadCommand::class)
                ->push([
                    'user_id' => $authorId,
                    'article_id' => $articleId,
                    'original_url' => $originalUrl,
                    'resource_file_name' => $resourceFileName,
                    'type' => GlobalArticleConst::REPLACE_IMAGE_TYPE_CONTENT,
                    'status' => GlobalUploadConst::UPLOAD_STATUS_SUCCESS
                ], GlobalConsoleConst::UPLOAD_LOG);
        }

        return true;
    }

    /**
     * 保存[spider_content]记录
     * @param string $url 链接地址
     * @param string $oldContent 没有替换图片地址的内容
     * @param string $newContent 替换图片地址后的内容
     * @return bool
     */
    private function saveSpiderContent($url, $oldContent, $newContent)
    {
        $spiderContent = SpiderContent::getInstance()->where(['url' => $url])->first();
        if (!$spiderContent) {
            $spiderContent = SpiderContent::getInstance();
        }
        return $spiderContent->save([
            'url' => $url,
            'content' => $newContent,
            'original_content' => $oldContent,
        ]);
    }

    /**
     * @param $articleId
     * @param $content
     * @return bool
     */
    private function saveArticleContent($articleId, $content)
    {
        $articleContent = SysArticleContent::getModel($articleId)->where(['article_id' => $articleId])->first();
        if (!$articleContent) {
            $articleContent = SysArticleContent::getModel($articleId);
        }
        $articleContent->article_id = $articleId;
        $articleContent->content = $content;
        return $articleContent->save();
    }
}
